home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / b&w.cpp < prev    next >
C/C++ Source or Header  |  1994-11-12  |  10KB  |  335 lines

  1. #include "b&w.h"
  2. #include "image.h"
  3. #include <string.h>
  4. #include "patterns.h"
  5.  
  6. inline int bw_pix(int color, int x, int y)            // Transform color pix
  7.     {                                                 // to B/W using pattern
  8.     int sx = x % 8;                                   // We suppose that 1st
  9.     int sy = y % 8;                                   // 16 patterns approxi-
  10.     return (pattern[color][sy]) & (1 << sx) ? 1 : 0;  // mates 16 colors
  11.     }
  12. ////////////////////////
  13. int pcx_dump(imageP image, uchar* new_image, int nplanes)
  14.     {
  15.     int x;  int count = 1;
  16.     int bplin = ((image->xmax + 7) / 8);
  17.     x = (nplanes - 1) * bplin;  // start of last plane
  18.     int shift = 2 * bplin;
  19.     int c = 0;
  20.  
  21.     unsigned char ch = image->data[x];
  22.  
  23.     while(1)
  24.     {
  25.     x++;
  26.     if(!(x % bplin))     // end of scan line or end of plane
  27.         {
  28.         if(x != bplin)  // not the end of scan line
  29.         x -= shift;
  30.         else           // end of scan line
  31.         {
  32.         if(count > 1 || (0xC0 == (0xC0 & ch)))
  33.             new_image[c++] = (count | 128 | 64);
  34.         new_image[c++] = ch;
  35.         break;
  36.         }
  37.         }
  38.  
  39.     if(ch == image->data[x])
  40.         {
  41.         if(count == 63)
  42.         {
  43.         if(count > 1 || (0xC0 == (0xC0 & ch)))
  44.             new_image[c++] = (count | 128 | 64);
  45.         new_image[c++] = ch;                     // Write pattern
  46.  
  47.         count = 1;
  48.         }
  49.         else
  50.         count++;
  51.         }
  52.     else
  53.         {
  54.         if(count > 1 || (0xC0 == (0xC0 & ch)))
  55.         new_image[c++] = (count | 128 | 64);
  56.         new_image[c++] = ch;                     // Write pattern
  57.  
  58.         count = 1;
  59.         ch = image->data[x];
  60.         }
  61.     }
  62.     return c;
  63.     }
  64. //////////////////////////
  65. void dither_image(imageP image, int y)
  66.     {
  67.     int xmax = image->xmax + 1;
  68.     for(int x = 0; x < xmax; x++)
  69.     image_put_pixel(image, loc(x, 0),
  70.         (bw_pix((uchar)(
  71.             image_get_pixel(image, loc(x, 0), 1, N_PLANES)),
  72.             x, y) ? 0 : 1), 1, 1);
  73.     }
  74. //////////////////////////
  75. int pcx_col_to_bw(char* src_name, char* dest_name)
  76.     {
  77.     if(!strcmp(dest_name, src_name))
  78.     return 0;
  79.     FILE* f = fopen(src_name, "rb");
  80.  
  81.     if(f == NULL)
  82.     {
  83.     fclose(f);
  84.     return 0;
  85.     }
  86.     FILE* f1 = fopen(dest_name, "wb");
  87.  
  88.     pcxheader p;
  89.     pcxstream pcxF(f);
  90.     get_pcx_header(&pcxF, &p);
  91. /*  The following variable is absolutely unnecessary. But Paintbrush use
  92.     16-bit rounded files - I don't know why. Use old_bplin for compatibility.
  93. */
  94.     int old_bplin = p.bplin;
  95.     int np = p.nplanes;
  96.     put_pcx_header(f1, &p, loc(p.x2 - p.x1 + 1, p.y2 - p.y1 + 1), 1, 1);
  97.     p.nplanes = np;
  98.  
  99.     imageP image = (imageP)malloc(old_bplin/*p.bplin*/ * p.nplanes + sizeof(imageType));
  100.     char* new_image = new uchar[p.bplin * p.nplanes];
  101.  
  102.     image->xmax = (p.x2 - p.x1 + 1 + 7) / 8 * 8 - 1;
  103.     image->ymax = 0;
  104.  
  105.     int x;  int y = 0;  int count;
  106.     int plane;
  107.  
  108.     plane = x = (p.nplanes - 1) * p.bplin;  // start of last plane
  109.     int height = p.y2 - p.y1 + 1;
  110.     int height1;
  111.     int shift = 2 * p.bplin;
  112.     while(y <= height)
  113.     {
  114.     unsigned char ch = pcxF.get();         // read char
  115.     if((ch & 0xC0 )==0xC0)                 // if two upper bits == 1
  116.         {
  117.         count = 63 & ch;                   // use 6 low bits as counter
  118.         ch = pcxF.get();
  119.         for(int j = 0; j < count; j++)
  120.         {
  121.         image->data[x] = ch;
  122.         x++;
  123.         if(x == old_bplin)//p.bplin)
  124.             {
  125.             dither_image(image, y);
  126.             int len = pcx_dump(image, new_image, 1);
  127.             fwrite(new_image, len, 1, f1);
  128.  
  129.             x = plane;
  130.             y++;
  131.             }
  132.         else
  133.             if(!(x % old_bplin))//p.bplin))
  134.             x -= shift;
  135.         }
  136.         }
  137.     else
  138.         {
  139.         (unsigned char)(image->data[x]) = ch;
  140.         x++;
  141.         if(x == old_bplin)//p.bplin)
  142.         {
  143.         dither_image(image, y);
  144.         int len = pcx_dump(image, new_image, 1);
  145.         fwrite(new_image, len, 1, f1);
  146.         x = plane;
  147.         y++;
  148.         }
  149.         else
  150.         if(!(x % old_bplin))//p.bplin))
  151.             x -= shift;
  152.  
  153.         }
  154.     }
  155.     delete image;
  156.     delete new_image;
  157.     fclose(f);
  158.     fclose(f1);
  159.     return 1;
  160.     }
  161.  
  162. //////////////////////////
  163. int pcx_bw_to_col(char* src_name, char* dest_name)
  164.     {
  165.     if(!strcmp(dest_name, src_name))
  166.     return 0;
  167.     FILE* f = fopen(src_name, "rb");
  168.  
  169.     if(f == NULL)
  170.     {
  171.     fclose(f);
  172.     return 0;
  173.     }
  174.  
  175.     pcxheader p;
  176.     pcxstream pcxF(f);
  177.     get_pcx_header(&pcxF, &p);
  178. /*  The following variable is absolutely unnecessary. But Paintbrush use
  179.     16-bit rounded files - I don't know why. Use old_bplin for compatibility.
  180. */
  181.     int old_bplin = p.bplin;
  182.     if(p.bitpx == 1 && p.nplanes == N_PLANES)
  183.     {
  184.     fclose(f);
  185.     return 0;
  186.     }
  187.     FILE* f1 = fopen(dest_name, "wb");
  188.     int np = p.nplanes;
  189.     put_pcx_header(f1, &p, loc(p.x2 - p.x1 + 1, p.y2 - p.y1 + 1), 1, 4);
  190.     p.nplanes = np;
  191.  
  192.     imageP image = (imageP)malloc(p.bplin * p.nplanes + sizeof(imageType));
  193.     char* new_image = new uchar[p.bplin * p.nplanes];
  194.  
  195.     image->xmax = (p.x2 - p.x1 + 1 + 7) / 8 * 8 - 1;
  196.     image->ymax = 0;
  197.  
  198.     int x;  int y = 0;  int count;
  199.     int plane;
  200.  
  201.     plane = x = (p.nplanes - 1) * p.bplin;  // start of last plane
  202.     int height = p.y2 - p.y1 + 1;
  203.     int height1;
  204.     int shift = 2 * p.bplin;
  205.     while(y <= height)
  206.     {
  207.     unsigned char ch = pcxF.get();         // read char
  208.     if((ch & 0xC0 )==0xC0)                 // if two upper bits == 1
  209.         {
  210.         count = 63 & ch;                   // use 6 low bits as counter
  211.         ch = pcxF.get();
  212.         for(int j = 0; j < count; j++)
  213.         {
  214.         image->data[x] = ch;
  215.         x++;
  216.         if(x == old_bplin)//p.bplin)
  217.             {
  218.             int len = pcx_dump(image, new_image, 1);
  219.             for(int t = 0; t < N_PLANES; t++)
  220.             {
  221.             fwrite(new_image, len, 1, f1);
  222.             }
  223.             x = plane;
  224.             y++;
  225.             }
  226.         else
  227.             if(!(x % old_bplin))//p.bplin))
  228.             x -= shift;
  229.         }
  230.         }
  231.     else
  232.         {
  233.         (unsigned char)(image->data[x]) = ch;
  234.         x++;
  235.         if(x == old_bplin)//p.bplin)
  236.         {
  237.         int len = pcx_dump(image, new_image, 1);
  238.         for(int t = 0; t < N_PLANES; t++)
  239.             fwrite(new_image, len, 1, f1);
  240.         x = plane;
  241.         y++;
  242.         }
  243.         else
  244.         if(!(x % old_bplin))//p.bplin))
  245.             x -= shift;
  246.  
  247.         }
  248.     }
  249.     delete image;
  250.     delete new_image;
  251.     fclose(f);
  252.     fclose(f1);
  253.     return 1;
  254.     }
  255. ///////////////////////// Demo code ////////////////////////
  256. /*
  257. #include <iostream.h>
  258. #include "dir.h"
  259. void main( int argc, char *argv[] )
  260.     {
  261.     char src_name[MAXPATH];
  262.     char dest_name[MAXPATH];
  263.  
  264.     if(argc < 3)
  265.     {
  266.     cout << "         ██████████████████████ FREEWARE █████████████████\n";
  267.     cout << "         ██                                             ██\n";
  268.     cout << "         ██ B&W Utility. (C) Stepan S. Vartanov, 1994.  ██\n";
  269.     cout << "         ██                                             ██\n";
  270.     cout << "         █████████████████████████████████████████████████\n";
  271.     cout << "╔═══════════════════════════════════════════════════════════════╗\n";
  272.     cout << "║ Task: Color to B&W PCX files conversion                       ║\n";
  273.     cout << "║ Usage:         b&w.exe <src file > <result> <pattern>         ║\n";
  274.     cout << "║ Example: b&w.exe color.pcx bw.pcx                             ║\n";
  275.     cout << "║         b&w.exe color.pcx bw.pcx 1000111101010101             ║\n";
  276.     cout << "║ file masks (*.pcx) does not supported                         ║\n";
  277.     cout << "║ Pattern determines, which of 16 colors should be black (0)    ║\n";
  278.     cout << "║ and which white (1)                                           ║\n";
  279.     cout << "╚═══════════════════════════════════════════════════════════════╝\n";
  280.     return;
  281.     }
  282.     if(argc >= 3)
  283.     {
  284.     strcpy(src_name, argv[1]);
  285.     strcpy(dest_name, argv[2]);
  286.     }
  287.     if(argc == 4)
  288.     {
  289.     if(strlen(argv[3]) < 16)
  290.         {
  291.         cout << "Use 16 colors in mask\n";
  292.         return;
  293.         }
  294.     for(int i = 0; i < 16; i++)
  295.         {
  296.         if(argv[3][i] == '0')
  297.         memset(pattern[i], 255, 8);
  298.         else
  299.         memset(pattern[i], 0, 8);
  300.         }
  301.     }
  302.  
  303.     if(!strcmp(dest_name, src_name))
  304.     {
  305.     pcx_col_to_bw(src_name, "tmp____u.pcy");
  306.     unlink(src_name);
  307.     rename("tmp____u.pcy", src_name);
  308.     }
  309.     else
  310.     pcx_col_to_bw(src_name, dest_name);
  311.  
  312. cout << "KNOW-HOW 5.0,Software development kit,Library in source codes (Borland C++ 3.x)\n";
  313. cout << "█████████████████████████████████████████████████████████████████████████████\n";
  314. cout << ">>> KNOW-HOW.Interface: GUI, LJ fonts(SFP) screen output, PCX, multiple over-\n";
  315. cout << "lapped windows, Scripts and macroses. DOS\n";
  316. cout << ">>> KNOW-HOW.DEBUGGER: For any situations, including hang-up. DOS\n";
  317. cout << ">>> KNOW_HOW.GRAPHICS: Using common code for any graphics library. Now it is\n";
  318. cout << "realized now for BGI and Windows GDI. Scrolling, Zooming, reflection of image,\n";
  319. cout << "rotations and complex rotations. Rotated and filled BGI fonts. DOS, WINDOWS\n";
  320. cout << ">>> KNOW-HOW.SLANG: Basic-like language. Multy-file programs, FOR, IF and so\n";
  321. cout << "on operators. User could derive from Slang the child class with new operators\n";
  322. cout << "to access functions of his concrete package. DOS, WINDOWS\n";
  323. cout << ">>> KNOW-HOW.VECTOR: Vector pictures editor. Simple KNOW-HOW.GRAPHICS\n";
  324. cout << "interpreter in DOS or Windows. Powerfull tool for maketing BGI, GDI and so on.\n";
  325. cout << ">>> KNOW-HOW.DRAW: PCX pictures editor. All standart image-editing functions.\n";
  326. cout << ">>> KNOW-HOW.PRINT: Create on disk virtual screen of any size, show, scroll\n";
  327. cout << "on screen or print on different printers with any deformation. DOS.\n";
  328. cout << ">>> KNOW-HOW.DATASHELL: Shell for Paradox Engine 3.01 or any other database\n";
  329. cout << "engine. View and edit tables and querries in Paradox-like style. Multy-table\n";
  330. cout << "QBE querries. Print reports in user-defined form. DOS.\n";
  331. cout << ">>> KNOW-HOW.GRAF: Business and scientific diagrams. Line, Markers,\n";
  332. cout << "Line-and-markers, Bar, 3d-Bar, Stacked bar graphs...  DOS, WINDOWS\n";
  333.     }
  334.  
  335. */